// Learn TypeScript:
//  - https://docs.cocos.com/creator/manual/en/scripting/typescript.html
// Learn Attribute:
//  - https://docs.cocos.com/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - https://docs.cocos.com/creator/manual/en/scripting/life-cycle-callbacks.html

import ScrollTextItem from "./ScrollTextItem";

const { ccclass, property, requireComponent } = cc._decorator;

@ccclass
export default class ScrollTextItemGroup extends cc.Component {

    private _index: number;
    private _value: string;
    private _items: cc.Node[];
    private _itemScript: ScrollTextItem[];
    public moveEndHandle: (index: number) => void;
    private _spaceY: number;
    private _moveRemind: number;
    private _startY: number;
    private _speedY: number;
    private _totalMoveTime: number;
    private _curMoveTime: number;
    private SPEED_Y: number = 300;
    private _moveDir:number = -1;//1向上 2向下
    // onLoad () {}

    start() {

    }

    public recycle() {
        this._value = '';
        this._index = -1;
        this._spaceY = 0;
        this._speedY = 0;
        this._moveRemind = 0;
        this._curMoveTime = 0;
        this._totalMoveTime = 0;
        this._startY = 0;
        this.moveEndHandle = null;
        this.node.removeFromParent();
    }

    public init(itemPrefab: cc.Prefab, index: number, value: string, height: number, itemNum: number = 2) {
        this._index = index;
        this._spaceY = height;
        this.node.width = itemPrefab.data.width * Math.abs(itemPrefab.data.scaleX)
        this.node.height = height;
        if (!this._items) {
            this._items = [];
            this._itemScript = [];
            for (let i = 0; i < itemNum; i++) {
                let item = this.node.children[i];
                if(!item){
                    item = cc.instantiate(itemPrefab);
                }
                if(item.parent != this.node){
                    item.parent = this.node;
                }
                let scrollTextItem = item.getComponent(ScrollTextItem);
                if(!scrollTextItem){
                    scrollTextItem = item.addComponent(ScrollTextItem)
                }
                this._itemScript[i] = scrollTextItem;
                this._items[i] = item;
            }
        }
        this.setValue(value, false);
    }

    private moveEnd() {
        this.node.y = 0;
        for (let i = 0; i < this._items.length; i++) {
            let node = this._items[i];
            node.y = -this._moveDir * i * this._spaceY;
            if(isNaN(Number(this._value))){
                this._itemScript[i].init(this._value)
            }else{
                this._itemScript[i].init(((Number(this._value) + i) % 10).toString())
            }
        }

        this._speedY = 0;
        this._moveRemind = 0;
        this._curMoveTime = 0;
        this._totalMoveTime = 0;
        this._startY = 0;
        if (this.moveEndHandle) {
            this.moveEndHandle(this._index);
        }
    }

    public setValue(value: string, withAction: boolean = true) {
        if (this._value == value) {
            return;
        }
        this._value = value;
        if (!withAction) {
            this.moveEnd()
        } else {
            if(isNaN(Number(value))){
                this.moveEnd()
                return
            }
            let firstScript = this._itemScript[0]
            let offset = Number(value) - Number(firstScript.data)
            if (offset <= 0) {
                offset += 10
            }
            this._moveRemind = this._moveDir * offset * this._spaceY;
            this._speedY = this._moveDir * this.SPEED_Y;
            this._curMoveTime = 0;
            this._totalMoveTime = this._moveRemind / this._speedY;
            this._startY = this.node.y;
        }
    }

    private easingTime(time: number) {
        time = cc.easeSineOut().easing(time)
        return time;
    }

    update(dt) {
        if (this._totalMoveTime > 0) {
            let timeDis = dt;
            let isEnd = false
            if ((this._curMoveTime - this._totalMoveTime) * (this._curMoveTime + dt - this._totalMoveTime) <= 0) {
                timeDis = this._totalMoveTime - this._curMoveTime;
                isEnd = true;
            }
            this._curMoveTime += timeDis;
            let persent = this._curMoveTime / this._totalMoveTime;
            persent = this.easingTime(persent);
            this.node.y = this._startY + persent * this._moveRemind;
            for (let i = 0; i < this._items.length; i++) {
                let node = this._items[i];
                if (this._moveDir * (node.y + this.node.y) >= this._spaceY) {
                    node.y = this._items[this._items.length - 1].y - this._moveDir * this._spaceY;
                    let script = this._itemScript[i];
                    let lastScript = this._itemScript[this._itemScript.length - 1];
                    let value = (Number(lastScript.data) + 1) % 10;
                    script.init(value.toString())
                    this._items.push(this._items.shift())
                    this._itemScript.push(this._itemScript.shift())
                    break;
                }
            }
            if (isEnd) {
                this.moveEnd();
            }
        }
    }
}
